using System.IO;
using Woolpert.Logging;

namespace Woolpert.Compression
{
    /// <summary>
    /// Zips Files up
    /// </summary>
    public sealed class FileZipUtility : IFileZipUtility
    {
        //todo: implement zipping filters

        private readonly IZip _zipApplication;

        /// <summary>
        /// Calls other constructor with default of 7-Zip for speedy compression
        /// </summary>
        public FileZipUtility()
            : this(new SevenZip())
        {
        }

        /// <summary>
        /// Creates a new zip utility that can zip files up
        /// </summary>
        /// <param name="zipApplication">Zip application to use on the back end</param>
        public FileZipUtility(IZip zipApplication)
        {
            Log.For(this).Debug(string.Format("Initializing {0}.", GetType()));
            this._zipApplication = zipApplication;
        }

        /// <summary>
        /// Zips files from a directory and subdirectories
        /// </summary>
        /// <param name="zipFilePath">The name of the zipped file</param>
        /// <param name="directory">directory to zip files up in</param>
        public void GenerateZipFile(string zipFilePath, string directory)
        {
            this.GenerateZipFile(zipFilePath, directory, true);
        }

        /// <summary>
        /// Zips files from a directory and subdirectories
        /// </summary>
        /// <param name="zipFilePath">The name of the zipped file</param>
        /// <param name="directory">directory to zip files up in</param>
        /// <param name="recursive">Would you like to zip up subdirectories as well?</param>
        public void GenerateZipFile(string zipFilePath, string directory, bool recursive)
        {
            Log.For(this).Info(string.Format("Attempting to zip up directory \"{0}\" to \"{1}\".", directory, zipFilePath));
            this._zipApplication.GenerateZipFile(zipFilePath, directory, recursive);
        }

        /// <summary>
        /// Zips a single file in to a compressed archive
        /// </summary>
        /// <param name="zipFilePath">The full name of the zip file that
        /// will be created, e.g., "C:\Temp\MyArchive.7z". Make 
        /// sure that the file extension is appropriate to the 
        /// archive format that you are creating, e.g., zip or 7z.</param>
        /// <param name="file">The file that you want to compress</param>
        public void GenerateZipFile(string zipFilePath, FileInfo file)
        {
            this._zipApplication.GenerateZipFile(zipFilePath, file);
        }

        /// <summary>
        /// Unzips all of the contents of a compressed archive
        /// to a single directory
        /// </summary>
        /// <param name="zipFilePath">The full name of the zip file
        /// that you want to uncompress, e.g., "C:\Temp\MyArchive.7z"</param>
        /// <param name="outputDirectory">An existing directory
        /// to which all the contents of the <paramref name="zipFilePath"/>
        /// will be extracted.</param>
        public void Unzip(string zipFilePath, string outputDirectory)
        {
            this._zipApplication.UnzipZipFile(zipFilePath, outputDirectory);
        }
    }
}